#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
pip install Flask==2.0.1
pip install flask-restx==0.5.1
pip install Werkzeug==2.0.1

flask_restx参考: 
https://blog.csdn.net/qq_27371025/article/details/126721480
https://flask-restx.readthedocs.io/en/latest/quickstart.html

生成可执行的client参考: 
https://github.com/swagger-api/swagger-codegen
"""
from flask import Flask
from flask_restx import Resource, Api, fields

app = Flask(__name__)
api = Api(app, version='1.0', title='demo swagger test  API', description=' Demo  Test  API')

# 定义命名空间,类似java 一个controller eg:  DemoController
# 如果不定义就是default
DEMO = api.namespace('DemoController', path='/')

#  -----------DemoController ---------------
# 定义swagger json mode 参数
demo_model = api.model('model', {
    'id': fields.Integer(readonly=True, description='任务唯一标识符'),
    'name': fields.String(required=True, description='姓名'),
    'type': fields.String(description='性别', enum=['保密', '男', '女'], default="保密"),
})

delete_demo_model = api.model('delete_demo_model', {
    'result': fields.Boolean(description='删除结果')
})


class demofunc(object):
    def __init__(self):
        self.counter = 0
        self.demos = []

    def get(self, id):
        for demo in self.demos:
            if demo['id'] == id:
                return demo

    def create(self, data):
        demo = data
        demo['id'] = self.counter = self.counter + 1
        self.demos.append(demo)
        return demo

    def update(self, id, data):
        demo = self.get(id)
        demo.update(data)
        return demo

    def delete(self, id):
        demo = self.get(id)
        self.demos.remove(demo)


demo_svc = demofunc()
# 创建demos基础数据
demo_svc.create({'name': 'liukang'})
demo_svc.create({'name': 'weiting', "type": "女"})


@DEMO.route('/demos')
class DemoList(Resource):

    @api.doc(id='post_demo', description='接口描述, 添加demo数据, demofunc().create()')
    @api.expect(demo_model, validate=True)
    @api.response(200, 'Success', demo_model)
    def post(self):
        """添加demo"""
        return demo_svc.create(api.payload)

    @api.doc('demo_list')
    @api.marshal_list_with(demo_model)
    def get(self):
        """获取demo列表"""
        return demo_svc.demos


@DEMO.route('/demos/<int:id>')
class Demo(Resource):

    @api.doc('get_demo')
    @api.response(200, 'Success', demo_model)
    def get(self, id):
        """获取demo"""
        return demo_svc.get(id)

    @api.doc('delete_demo')
    @api.response(200, 'Success', delete_demo_model)  # TODO: 删除成功返回值是空字典, 但是swagger不知道怎么定义，暂时使用 字符串类型的空字典
    def delete(self, id):
        """删除demo"""
        try:
            demo_svc.delete(id)
            return {"result": True}
        except BaseException as x:
            return {"result": False}

    @api.doc('put_demo')
    @api.expect(demo_model, validate=True)
    @api.response(200, 'Success', demo_model)
    def put(self, id):
        """修改demo"""
        return demo_svc.update(id, api.payload)


if __name__ == '__main__':
    app.run(debug=True, host="0.0.0.0", port=8000)
